package cn.wsalix.biz.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.anlaser.form.UploadFileForm;
import cn.anlaser.page.QuerySpecification;
import cn.anlaser.service.impl.SimpleServiceImpl;
import cn.anlaser.type.FileTypeEnum;
import cn.anlaser.type.ImageTypeEnum;
import cn.anlaser.utils.BeanMapper;
import cn.anlaser.utils.DynamicSpecifications;
import cn.anlaser.utils.SearchFilter;
import cn.anlaser.utils.SearchFilter.Operator;
import cn.wsalix.biz.entity.ImageFile;
import cn.wsalix.biz.entity.RelationImage;
import cn.wsalix.biz.form.ImageFileForm;
import cn.wsalix.biz.repository.ImageFileRepository;
import cn.wsalix.biz.repository.RelationImageRepository;
import cn.wsalix.biz.service.AdvertiseService;
import cn.wsalix.biz.service.ArticleService;
import cn.wsalix.biz.service.CategoryService;
import cn.wsalix.biz.service.ImageFileService;
import cn.wsalix.observable.service.FileUploadService;
import cn.wsalix.shop.service.BrandService;
import cn.wsalix.shop.service.OriginService;
import cn.wsalix.shop.service.ProductService;
import cn.wsalix.user.service.UserInfoService;

@Service("imageFileService")
public class ImageFileServiceImpl extends
		SimpleServiceImpl<ImageFileForm, ImageFileRepository, ImageFile>
		implements ImageFileService {
	@Autowired
	private ImageFileRepository imageFileRepository;
	@Autowired
	private RelationImageRepository relationImageRepository;

	@Override
	public String module() {
		return "/biz/image_file";
	}

	@Override
	public ImageFileRepository getRepository() {
		return imageFileRepository;
	}

	@Override
	public Class<ImageFile> getEntityClazz() {
		return ImageFile.class;
	}

	@Override
	public Map<String, SearchFilter> buildByForm(ImageFileForm form) {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);

		if (form.getImageType() != null) {
			filters.put("imageType", new SearchFilter("imageType", Operator.EQ,
					form.getImageType()));
		}

		return filters;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.anlaser.service.impl.CommonServiceImpl#delete(java.lang.Long)
	 * 删除图片记录，须先删除图片关联表记录
	 */
	@Transactional
	@Override
	public void delete(Long id) {
		relationImageRepository.deleteByImageId(id);
		super.delete(id);
	}

	@Transactional
	@Override
	public void addRelation(Long imageId, Long fkId, String imageType) {
		ImageFile imageFile = findById(imageId);
		RelationImage relationImage = new RelationImage();
		relationImage.setFkId(fkId);
		relationImage.setCategory(categoryService.findByCodeOne(imageType));
		relationImage.setImageFile(imageFile);
		relationImageRepository.save(relationImage);
	}

	@Transactional
	@Override
	public void deleteRelation(Long relationId) {
		relationImageRepository.delete(relationId);
	}

	/*
	 * @Override public List<ImageFile> findByAdId(Long adId) { ImageFileForm
	 * ImageFileForm = new ImageFileForm(); ImageFileForm.setFkId(adId);
	 * ImageFileForm.setType(FileTypeEnum.ad); QuerySpecification<ImageFile>
	 * spec = DynamicSpecifications
	 * .bySearchFilter(buildByForm(ImageFileForm).values(), getEntityClazz());
	 * return ImageFileRepository.findAll(spec); }
	 */
	@Transactional
	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof FileUploadService) {
			FileUploadService fileUploadService = (FileUploadService) o;
			if (arg instanceof UploadFileForm) {
				UploadFileForm form = (UploadFileForm) arg;
				if (form.getType().ordinal() == FileTypeEnum.image.ordinal()) {
					ImageFileForm imageFileForm = BeanMapper.map(form,
							ImageFileForm.class);
					ImageFile imageFile = super.add(imageFileForm);
					// if fkId not null
					if (form.getFkId() != null && form.getFkId() != 0) {// 图片关系新增，无修改，只有图片删除时须删除记录
						if (form.getImageType() != null) {
							RelationImage relationImage = new RelationImage();
							relationImage.setImageFile(imageFile);
							relationImage.setFkId(form.getFkId());
							relationImage.setCategory(categoryService.findByCodeOne(form.getImageType()));
							relationImageRepository.save(relationImage);
						}
					}
				}
			}

		}

	}

	@Autowired
	private ArticleService articleService;
	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private AdvertiseService advertiseService;
	@Autowired
	private CategoryService categoryService;
	@Autowired
	private ProductService productService;
	@Autowired
	private BrandService brandService;
	@Autowired
	private OriginService originService;

	@Override
	public Object findFkByForm(String imageType, Long fkId) {
		switch (ImageTypeEnum.findByName(imageType)) {
		case ad:
			return advertiseService.findById(fkId);
		case article:
			return articleService.findById(fkId);
		case avatar:
			return userInfoService.findById(fkId);
		case brand:
			return brandService.findById(fkId);
		case category:
			return categoryService.findById(fkId);
		case origin:
			return originService.findById(fkId);
		case product:
			return productService.findById(fkId);
		case unknown:
			break;
		default:
			break;
		}
		return null;
	}

	public List<RelationImage> findRelationImage(String imageType,
			Long fkId) {
		ImageFileForm form = new ImageFileForm();
		form.setImageType(imageType);
		form.setFkId(fkId);
		Map<String, SearchFilter> filterMap = buildRelationImageByForm(form);
		if (form.getFkId() != null) {
			filterMap.put("fkId",
					new SearchFilter("fkId", Operator.EQ, form.getFkId()));
		}
		if (form.getImageType() != null) {
			filterMap.put("imageType", new SearchFilter("imageType",
					Operator.EQ, form.getImageType()));
		}
		QuerySpecification<RelationImage> spec = DynamicSpecifications
				.bySearchFilter(filterMap.values(), RelationImage.class);

		return relationImageRepository.findAll(spec);
	}

	@Override
	public Page<ImageFile> findPageByFkId(Long catId, Long fkId) {
		List<ImageFile> imageFileLst = relationImageRepository
				.findByCatIdAndFkid(fkId, catId);
		/*
		 * ImageFileForm form=new ImageFileForm(); Map<String, SearchFilter>
		 * filterMap=buildRelationImageByForm(form);
		 * QuerySpecification<ImageFile> spec =
		 * DynamicSpecifications.bySearchFilter(filterMap.values(),
		 * ImageFile.class);
		 * 
		 * relationImageRepository.findAll();
		 */
		Page<ImageFile> page = new PageImpl<ImageFile>(imageFileLst);
		return page;
	}

	public Map<String, SearchFilter> buildRelationImageByForm(ImageFileForm form) {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);

		if (form.getImageType() != null) {
			filters.put("imageType", new SearchFilter("imageType", Operator.EQ,
					form.getImageType()));
		}

		return filters;
	}

	@Override
	public List<ImageFile> findByFkId(Long catId, Long fkId) {
		return relationImageRepository.findByCatIdAndFkid(fkId, catId);
	}

}
